package cn.epsilon3.scheduled;

import cn.epsilon3.configBean.InitializingAsyncScheduledConfig;
import cn.epsilon3.utils.SpringContextUtils;

import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @description 计划调度
 * @author: epsilon3
 * @date: 2023/9/5 10:37
 */

public class E3AsyncScheduled {

    /**
     * yaml配置映射实体
     */
    private final InitializingAsyncScheduledConfig asyncScheduledConfig = SpringContextUtils.getBean(InitializingAsyncScheduledConfig.class);

    /**
     * 调度线程池
     */
    private final ScheduledExecutorService scheduledExecutorService = (ScheduledExecutorService) SpringContextUtils.getBean("e3ScheduledExecutorService");

    /**
     * 单例构造使用
     */
    private static volatile E3AsyncScheduled e3AsyncScheduled;

    /**
     * 禁止new
     */
    private E3AsyncScheduled() {

    }

    /**
     * 防止重复创建
     */
    private static E3AsyncScheduled instance() {
        if (e3AsyncScheduled == null) {
            synchronized (E3AsyncScheduled.class) {
                if (e3AsyncScheduled == null) {
                    e3AsyncScheduled = new E3AsyncScheduled();
                }
            }
        }
        return e3AsyncScheduled;
    }

    /**
     * 获取
     *
     * @return 实例化
     */
    public static E3AsyncScheduled in() {
        return instance();
    }

    /**
     * 执行计划
     *
     * @param task 任务计划
     */
    public void start(TimerTask task) {
        scheduledExecutorService.schedule(task, asyncScheduledConfig.getDelayTime(), TimeUnit.MILLISECONDS);
    }

    /**
     * 关闭调度服务
     * 调用后并不会立马停止，设置为SHUTDOWN状态，未执行的任何将会舍弃，正在执行的将会继续执行
     * 在SHUTDOWN状态时，将会等待指定等待时间，在等待时间结束后将会设置为STOP状态
     * 如果还有未执行完的任务将会强制打断
     */
    public void end() {
        if (!scheduledExecutorService.isShutdown()) {
            scheduledExecutorService.shutdown();
            try {
                if (!scheduledExecutorService.awaitTermination(asyncScheduledConfig.getStopWaitTime(),TimeUnit.SECONDS)) {
                    scheduledExecutorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                scheduledExecutorService.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
}
